package com.ybwh.springboot2.anno.reference;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * <p>
 * 处理 RpcReference 的属性注入，参照 dubbo的 ReferenceAnnotationBeanPostProcessor
 * </p>
 *
 * @author fanbeibei
 * @version 1.0.0
 * @date 2023/5/17 16:31
 */
@Slf4j
public class RpcReferenceAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
//        System.out.print("beanName:" + beanName + "执行..postProcessAfterInstantiation\n");


        // 会影响postProcessProperties 是否执行，返回false不执行
        return true;
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
//        System.out.print("beanName:" + beanName + "执行..postProcessBeforeInstantiation\n");

        // 返回值可以用来代替原本该生成的目标对象的实例,null表示不替换

        return null;

//        if(!Objects.equals(RemoteIface.class,beanClass)){
//            return null;
//        }
//
//
//        //利用cglib 其 生成动态代理
//        Enhancer enhancer = new Enhancer();
//        enhancer.setSuperclass(beanClass);
//        enhancer.setCallbacks(new Callback[]{
//                new MethodInterceptor() {
//                    @Override
//                    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
//
//                        log.info("-------------args={}", args);
//
////                        return Long.valueOf(2342L);
//                        return method.invoke(obj, args);
//
//                    }
//                }
//        });
//
//        return enhancer.create();

    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws
            BeansException {
        // spring 自身对属性的处理
        System.out.println("beanName:" + beanName + "执行..postProcessProperties,"+pvs.contains("remoteIface"));
        // 遍历属性 找到@RpcReference注入
        ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
            @Override
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {

                RpcReference annotation = field.getAnnotation(RpcReference.class);

                if (annotation != null) {

                    if (Modifier.isStatic(field.getModifiers())) {
                        if (log.isWarnEnabled()) {
                            log.warn("@" + RpcReference.class.getName() + " is not supported on static fields: " + field);
                        }
                        return;
                    }


                    // 这里进行注入
                    System.out.println("----------------------"+field.getName()+"    "+field.getType());

                }

            }
        });




        return pvs;
    }



    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
